package com.example.takeaway.config;

import io.minio.*;
import io.minio.http.Method;
import lombok.SneakyThrows;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.io.ByteArrayInputStream;
import java.io.InputStream;

/**
 * @author 邢晨旭
 * {@code @date} 2023/10/10
 */
@Component
public class MinioTemplate {

    @Resource
    MinioClient minioClient;

    @Resource
    OssConfig ossConfig;

    /**
     * 判断桶是否存在
     *
     * @param bucketName 桶名称
     */
    @SneakyThrows
    public boolean bucketExists(String bucketName) {
        return minioClient.bucketExists(BucketExistsArgs.builder()
                .bucket(bucketName)
                .build());
    }

    /**
     * 创建桶
     *
     * @param bucketName 桶名称
     */
    @SneakyThrows
    public void makeBucket(String bucketName) {
        if (!bucketExists(bucketName)) {
            minioClient.makeBucket(MakeBucketArgs.builder()
                    .bucket(bucketName)
                    .build());
        }
    }

    /**
     * 删除桶 (只能删除空桶,否则会报错)
     *
     * @param bucketName 桶名称
     */
    @SneakyThrows
    public void removeBucket(String bucketName) {
        minioClient.removeBucket(RemoveBucketArgs.builder()
                .bucket(bucketName)
                .build());
    }

    /**
     * 流的形式上传文件
     *
     * @param inputStream 文件流
     * @param bucketName  桶名称
     * @param fileName    文件名称
     * @param contentType 文件类型
     */
    @SneakyThrows
    public void putObject(InputStream inputStream, String bucketName, String fileName, String contentType) {
        minioClient.putObject(PutObjectArgs.builder()
                .bucket(bucketName)
                .object(fileName)
                .stream(inputStream, inputStream.available(), -1)
                .contentType(contentType)
                .build());
    }

    /**
     * 字节数组的形式上传文件
     *
     * @param bytes       文件字节数组
     * @param bucketName  桶名称
     * @param fileName    文件名称
     * @param contentType 文件类型
     */
    @SneakyThrows
    public void putObject(byte[] bytes, String bucketName, String fileName, String contentType) {
        ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
        putObject(inputStream, bucketName, fileName, contentType);
    }

    /**
     * 获取文件流
     *
     * @param bucketName 桶名称
     * @param fileName   文件名称
     * @return InputStream 文件流
     */
    @SneakyThrows
    public InputStream getObject(String bucketName, String fileName) {
        return minioClient.getObject(GetObjectArgs.builder()
                .bucket(bucketName)
                .object(fileName)
                .build());
    }

    /**
     * 删除文件
     *
     * @param bucketName 桶名称
     * @param fileName   文件名称
     */
    @SneakyThrows
    public void removeObject(String bucketName, String fileName) {
        minioClient.removeObject(RemoveObjectArgs.builder()
                .bucket(bucketName)
                .object(fileName)
                .build());
    }


    /**
     * 流的形式上传文件
     *
     * @param inputStream 文件流
     * @param fileName    文件名称
     * @param contentType 文件类型
     */
    @SneakyThrows
    public void putObject(InputStream inputStream, String fileName, String contentType) {
        minioClient.putObject(PutObjectArgs.builder()
                .bucket(ossConfig.getBucket())
                .object(fileName)
                .stream(inputStream, inputStream.available(), -1)
                .contentType(contentType)
                .build());
    }

    /**
     * 字节数组的形式上传文件
     *
     * @param bytes       文件字节数组
     * @param fileName    文件名称
     * @param contentType 文件类型
     */
    @SneakyThrows
    public void putObject(byte[] bytes, String fileName, String contentType) {
        ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
        putObject(inputStream, ossConfig.getBucket(), fileName, contentType);
    }

    /**
     * 获取文件流
     *
     * @param fileName 文件名称
     * @return InputStream 文件流
     */
    @SneakyThrows
    public InputStream getObject(String fileName) {
        return minioClient.getObject(GetObjectArgs.builder()
                .bucket(ossConfig.getBucket())
                .object(fileName)
                .build());
    }

    /**
     * 删除文件
     *
     * @param fileName 文件名称
     */
    @SneakyThrows
    public void removeObject(String fileName) {
        minioClient.removeObject(RemoveObjectArgs.builder()
                .bucket(ossConfig.getBucket())
                .object(fileName)
                .build());
    }

    @SneakyThrows
    public String getPresignedObjectUrl(String fileName) {
        return minioClient.getPresignedObjectUrl(GetPresignedObjectUrlArgs.builder()
                .method(Method.PUT)
                .bucket(ossConfig.getBucket())
                .object(fileName)
                .expiry(60 * 5)
                .build());
    }

}
